﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using Koossery.MVCwin.Controller.impl;
using Koossery.MVCwin.Controller.itf;
using Koossery.MVCwin.ControllerManager.itf;
using Koossery.MVCwin.Data;
using Koossery.MVCwin.Properties;
using Koossery.MVCwin.Util;
using Koossery.MVCwin.Views.itf;

using log4net;

namespace Koossery.MVCwin.Views.impl
{
	/// <author>Mohamadou Yacoubou</author>
	/// <summary>
	/// Base view implementation
	/// </summary>
	public partial class BaseView : Form, IView
	{
		#region Static Fields

		private static readonly ILog log = log4net.LogManager.GetLogger("Koossery.MVCwin");

		#endregion Static Fields

		#region Fields

		/// <summary>
		/// An instance of the controllerManger is passed to the view; is injected by
		/// an IoC framework (unity, spring, pico, etc.)
		/// </summary>
		private IControllerManager _controllerManager;

		/// <summary>
		/// Indicates that the view is a child view
		/// </summary>
		private bool _isChildForm = true;

		/// <summary>
		///<see cref="Session" />
		/// </summary>
		private Session _session;

		/// <summary>
		/// Current view's name
		/// </summary>
		private string _viewName;

		#endregion Fields

		#region Constructors

		/// <summary>
		/// Constructeur de la Vue
		/// </summary>
		public BaseView()
		{
			base.Closing += new CancelEventHandler(this.BaseView_Closing);
			InitializeComponent();
		}

		#endregion Constructors

		#region Public Properties

		/// <summary>
		/// <see cref="Controller"/>
		/// </summary>
		public IControllerManager ControllerManager
		{
			get
			{
			    return this._controllerManager;
			}
			set
			{
			    if (this._controllerManager == null)
			        this._controllerManager = value;
			}
		}

		/// <summary>
		/// <see cref="_isChildForm"/>
		/// </summary>
		public bool IsChildForm
		{
			get
			{
			    return _isChildForm;
			}
			set
			{
			    _isChildForm = value;
			}
		}

		/// <summary>
		/// <see cref="Session"/>
		/// </summary>
		public Session Session
		{
			set
			{
			    if (_session != null) throw new Exception(Resources.InitializedSessionException);
			    _session = value;
			}
		}

		/// <summary>
		/// Current view's name
		/// </summary>
		public string ViewName
		{
			get
			{
			    return this._viewName;
			}
			set
			{
			    this._viewName = value;
			    this.Text = this._viewName;
			}
		}

		#endregion Public Properties

		#region Private Methods

		/// <summary>
		/// Disable closing view by cancelling the closing event
		/// </summary>
		/// <param name="sender">The sender object</param>
		/// <param name="e">The cancel event parameter</param>
		private void BaseView_Closing(object sender, CancelEventArgs e)
		{
			e.Cancel = true;
		}

		#endregion Private Methods

		#region Public Methods

		/// <summary>
		/// Initialize DataSources
		/// </summary>
		public virtual void BindDataToView()
		{
            //Retrieving the manager
            ControllerManager.impl.ControllerManager manager = this.ControllerManager as ControllerManager.impl.ControllerManager;

            //Subscribing to events
            manager.BgAsyncMethods.ProgressChanged += new ProgressChangedEventHandler(BgAsyncMethods_ProgressChanged);
            manager.BgAsyncMethods.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BgAsyncMethods_RunWorkerCompleted);
		}

        protected virtual void BgAsyncMethods_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //Hiding the progress bar panel
            this.plProcess.Visible = false;
        }

        protected virtual void BgAsyncMethods_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //Showing the progress bar
            if (!plProcess.Visible) plProcess.Visible = true;
            plProcess.Refresh();
        }

		/// <summary>
		/// Display the view
		/// </summary>
		public virtual void DisplayView()
		{
			BindDataToView();
            if (this.Visible == true) return;
            this.Show();
		}

		/// <summary>
		/// Gets the bool which indicates wheter the error message is displayed or not
		/// </summary>
		/// <returns>La valeur boolenne reprsentant la visibilit</returns>
		public bool GetContextVisibility()
		{
			return this._session.MessageData.LblContextMessageVisibility;
		}

		/// <summary>
		/// <see cref="Session"/>
		/// </summary>
		/// <param name="messageType"></param>
		/// <returns></returns>
		public string GetMessage(MessageType messageType)
		{
			return this._session.GetMessage(messageType);
		}

		/// <summary>
		/// Get the session data from the key name
		/// </summary>
		/// <param name="key">The session data key</param>
		/// <returns>The session data</returns>
		public AbstractBaseData GetSessionData(string key)
		{
            return this._session[key];
		}

		/// <summary>
		/// Hide the view
		/// </summary>
		public virtual void HideView()
		{
            //Retrieving the manager
            ControllerManager.impl.ControllerManager manager = this.ControllerManager as ControllerManager.impl.ControllerManager;

            //Removing events
            manager.BgAsyncMethods.ProgressChanged -= BgAsyncMethods_ProgressChanged;
            manager.BgAsyncMethods.RunWorkerCompleted -= BgAsyncMethods_RunWorkerCompleted;
            
			this.Hide();
		}

		/// <summary>
		/// Invoke an action of the controller
		/// </summary>
		/// <param name="controllerName">The controller name</param>
		public void InvokeController(string controllerName)
		{
			this.ControllerManager.Invoke(controllerName);
		}

		/// <summary>
		/// Invoke an action of the controller
		/// </summary>
		/// <param name="controllerName">The controller name</param>
		/// <param name="actionName">The action name</param>
		public void InvokeController(string controllerName, string actionName)
		{
			this.ControllerManager.Invoke(controllerName, actionName);
		}

		#endregion Public Methods
	}
}